from gevent import monkey
monkey.patch_all()

from gevent.pool import Pool
from queue import Queue
import schedule
import time

import settings
from core.db.mongo_pool import MongoPool
from utils.log import logger
from core.proxy_validate.httpbin_validator import check_proxy


class ProxyTester(object):

    def __init__(self):
        self.mongo_pool = MongoPool()
        self.pool = Pool()   # 协程池
        self.queue = Queue()  # 队列

    def __check_one_proxy(self):
        proxy = self.queue.get()
        proxy = check_proxy(proxy)
        # 如果速度为-1， 说明请求失败
        if proxy.speed == -1:
            proxy.score -= 1

            # 若分数降为0，就删除该代理IP
            if proxy.score <= 0:
                self.mongo_pool.delete_one(proxy)
                logger.info("删除代理：{}".format(proxy))
            else:
                # 若分数不为0， 就更新当前代理
                self.mongo_pool.update(proxy)
        else:
            # 如果请求成功，恢复最高分数
            proxy.score = settings.MAX_SCORE
            self.mongo_pool.update(proxy)

        self.queue.task_done()

    def __check_callback(self, temp):
        self.pool.apply_async(self.__check_one_proxy, callback=self.__check_callback)

    def run(self):
        # 获取所有的代理IP
        all_proxy = self.mongo_pool.find_all()
        if all_proxy is None:
            logger.info("代理池为空")
            return

        for proxy in all_proxy:
            # 把代理放入队列
            self.queue.put(proxy)

        # 开启多个协程执行检查IP的任务
        for i in range(settings.TESTER_PROXY_ANSYC_COUNT):
            # 通过异步回调，使用死循环不断执行这个方法
            self.pool.apply_async(self.__check_one_proxy, callback=self.__check_callback)

        # 主线程等待异步完成
        self.queue.join()

    @staticmethod
    def start():
        pt = ProxyTester()
        pt.run()
        schedule.every(settings.ESTER_PROXY_TIME).hours.do(pt.run)
        while True:
            schedule.run_pending()
            time.sleep(5)

if __name__ == "__main__":
    ProxyTester().run()
    # ProxyTester.start()
